package com.weiyuwqj.server.service.sys.module;

import com.weiyuwqj.api.util.Sms;
import com.weiyuwqj.server.mapper.*;
import com.weiyuwqj.api.constant.Constants;
import com.weiyuwqj.api.constant.Message;
import com.weiyuwqj.api.model.*;
import com.weiyuwqj.api.model.vo.UserVo;
import com.weiyuwqj.api.service.NoticePush;
import com.weiyuwqj.api.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by huzj on 2016/8/24.
 */

@Component
public class ConfigTicketModule {

    @Autowired
    SysConfigTicketRuleMapper ticketRuleMapper;

    @Autowired
    SysConfigTicketUserMapper ticketUserMapper;

    @Autowired
    SysConfigTicketMapper configTicketMapper;

    @Autowired
    BasTicketMapper ticketMapper;

    @Autowired
    BasCouponMapper couponMapper;

    @Autowired
    SysNoticeTypeMapper noticeTypeMapper;

    @Autowired
    BasUserMapper userMapper;

    @Autowired
    SysNoticeMapper noticeMapper;

    @Autowired
    SysSiteMailMapper siteMailMapper;

    @Autowired
    NoticePush noticePush;

    @Autowired
    SysAppClientMapper appClientMapper;

    @Autowired
    SysPushLogMapper pushLogMapper;

    @Autowired
    SysAppSettingsMapper appSettingsMapper;

    @Autowired
    BusItemInvestMapper investMapper;

    public Map  addTicket(TicketParamEntity param) {
        //根据nid和投资类型获取可用的规则
        List<SysConfigTicketRule> ruleList = ticketRuleMapper.listUsableByNid(param.getNid());
        if (ruleList == null) {
            Map map = new HashMap();
            map.put("message", "not_has_activity");
            map.put("result", "fail");
            return map;
        }
        if (param.getNid().equals(Constants.redeem_code_nid)) {
            SysConfigTicketRule rule = ticketRuleMapper.getByInviteCode(param.getRedeemCode());
            if (rule == null) {
                Map map = new HashMap();
                map.put("message", "invite_code_error");
                map.put("result", "fail");
                return map;
            }
        }
        Integer userId = param.getUserId();
        for (SysConfigTicketRule rule : ruleList) {
            //规则类型时指定用户时匹配用户id
            if (rule.getUsersType() == 1) {
                if (ticketUserMapper.match(userId, rule.getId())
                        == null) {
                    Map map = new HashMap();
                    map.put("message", "user_not_in_activity");
                    map.put("result", "fail");
                    return map;
                }
            }
            Integer remainCount = 0;
            //判断限领
            if (rule.getLimitType() != null && rule.getTotalLimit() != null) {
                Map limitMap = new HashMap();
                if (rule.getLimitType() == 0) {
                    Date now = new Date();
                    Date beginDateTime = DateUtils.getDayStartTime(now);
                    Date endDateTime = DateUtils.getNextDayStartTime(now);
                    limitMap.put("userId", userId);
                    limitMap.put("beginDateTime", beginDateTime);
                    limitMap.put("endDateTime", endDateTime);
                    limitMap.put("ruleId", rule.getId());
                } else if (rule.getLimitType() == 1) {
                    limitMap.put("userId", userId);
                    limitMap.put("ruleId", rule.getId());
                }
                Integer couponCount = couponMapper.statCouponCount(limitMap);
                Integer ticketCount = ticketMapper.statTicketCount(limitMap);
                if ((couponCount + ticketCount) >= rule.getTotalLimit()) {
                    Map map = new HashMap();
                    map.put("message", "ticket_get_out_limit");
                    map.put("result", "fail");
                    return map;
                }
                remainCount = rule.getTotalLimit()-(couponCount + ticketCount);
            }
            //判断总数量
            if (rule.getTotalCount() != null && rule.getTotalCount() > 0) {
                Map limitMap = new HashMap();
                limitMap.put("ruleId", rule.getId());
                Integer couponCount = couponMapper.statCouponCount(limitMap);
                Integer ticketCount = ticketMapper.statTicketCount(limitMap);
                if ((couponCount + ticketCount) >= rule.getTotalCount()) {
                    Map map = new HashMap();
                    map.put("message", "ticket_get_out_limit");
                    map.put("result", "fail");
                    return map;
                }
                if(remainCount> (rule.getTotalCount()-(couponCount + ticketCount))){
                    remainCount=rule.getTotalCount()-(couponCount + ticketCount);
                }
            }
            Integer defaultSendTimes=1;
            //满额可获得的卡劵数量
            if (rule.getNid().equals(Constants.total_invest_nid)) {
                Map investMap = new HashMap();
                investMap.put("userId", userId);
                investMap.put("beginDateTime", rule.getBeginTime());
                investMap.put("endDateTime", rule.getEndTime());
                BigDecimal totalAmount = investMapper.statTotalAmount(investMap);
                Map limitMap = new HashMap();
                limitMap.put("userId", userId);
                limitMap.put("ruleId", rule.getId());
                Integer couponCount = couponMapper.statCouponCount(limitMap);
                Integer ticketCount = ticketMapper.statTicketCount(limitMap);
                    Integer receivedCount=couponCount+ticketCount;
                defaultSendTimes =totalAmount.divideToIntegralValue(rule.getMinimumAmount()).intValue()-receivedCount;
                if(defaultSendTimes>remainCount){
                    defaultSendTimes = remainCount;
                }
                dealInsertTicket(param, rule,defaultSendTimes);
                return Message.OK;
            }
            // 兑换码
            if (rule.getNid().equals(Constants.redeem_code_nid)) {
                if (param.getRedeemCode().equals(rule.getRedeemCode())) {
                    dealInsertTicket(param, rule,defaultSendTimes);
                }
            }
            //判断是否有资金门槛
            if (isPosDec(rule.getMinimumAmount())
                    && isPosDec(param.getAmount())) {
                SysConfigTicketRule lvRule = getRuleWithLevel(param.getAmount(), ruleList);
                if (rule.equals(lvRule)) {
                    dealInsertTicket(param, rule,defaultSendTimes);
                }
            }
            //判断是否有锁定期限门槛
            if (isPosInt(rule.getLockLife())
                    && isPosInt(param.getLockLife())) {
                SysConfigTicketRule lvRule = getRuleWithLevel(param.getLockLife(), ruleList);
                if (rule.equals(lvRule)) {
                    dealInsertTicket(param, rule,defaultSendTimes);
                }
            }

            if (!isPosDec(rule.getMinimumAmount())
                    && !isPosInt(rule.getLockLife())) {
                dealInsertTicket(param, rule,defaultSendTimes);
            }
        }
        return Message.OK;
    }

    //增加卡劵
    private void dealInsertTicket(TicketParamEntity param, SysConfigTicketRule rule, Integer sendTimes) {
        Map map = new HashMap();
        map.put("ruleId", rule.getId());
        Date now = new Date();
        System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        List<SysConfigTicket> configTicketList = configTicketMapper.getList(map);
        for (int i = 0; i < sendTimes; i++) {
            for (SysConfigTicket configTicket : configTicketList) {
                if (configTicket.getType() == 1) {
                    BasCoupon coupon = new BasCoupon();
                    coupon.setRuleId(rule.getId());
                    coupon.setCouponName(rule.getName());
                    coupon.setUserId(param.getUserId());
                    coupon.setWay(rule.getName());
                    coupon.setAmount(configTicket.getAmount());
                    Date expiredTime = addDay(new Date(), configTicket.getExpiredLife());
                    coupon.setExpiredTime(DateUtils.setDayLast(expiredTime));
                    coupon.setStatus(2);
                    coupon.setRequireAmount(configTicket.getRequireAmount());
                    coupon.setAddtime(now);
                    coupon.setInvestId(0);
                    coupon.setAddip(param.getAddIp());
                    coupon.setScope(configTicket.getScope());
                    couponMapper.insert(coupon);
                } else if (configTicket.getType() == 2) {
                    BasTicket ticket = new BasTicket();
                    ticket.setRuleId(rule.getId());
                    ticket.setTicketName(rule.getName());
                    ticket.setUserId(param.getUserId());
                    ticket.setWay(rule.getName());
                    ticket.setRate(configTicket.getRate());
                    Date expiredTime = addDay(new Date(), configTicket.getExpiredLife());
                    ticket.setExpiredTime(DateUtils.setDayLast(expiredTime));
                    ticket.setStatus(2);
                    ticket.setRequireAmount(configTicket.getRequireAmount());
                    ticket.setAddtime(now);
                    ticket.setInvestId(0);
                    ticket.setUsefulLife(configTicket.getUsefulLife());
                    ticket.setAddip(param.getAddIp());
                    ticket.setScope(configTicket.getScope());
                    ticketMapper.insert(ticket);
                }
            }
        }
        if(sendTimes >= 1){
            noticeUser(param,null, "卡券奖励", rule);
        }

    }

    //通知用户
    private void noticeUser(TicketParamEntity param,
                            BigDecimal value,
                            String title,
                            SysConfigTicketRule rule) {
        BasUser user = userMapper.selectByPrimaryKey(param.getUserId());
        if (user == null) {
            return;
        }
        SysAppSettings appSettings = appSettingsMapper.getAppSettingsByUserId(param.getUserId());
        Date now = new Date();
        if (rule.getWhetherSms() == 1 && (appSettings == null || appSettings.getWhetherSms() == 1)) {
           /* SysNoticeType sysNoticeType = noticeTypeMapper.getNoticeTypeByNid(param.getNid()+"_award_sms");
            if (sysNoticeType == null){
                return;
            }
            String content = rule.getTypeContent().
                    replace(Constants.AWARDTYPE, type).
                    replace(Constants.AWARD,value.toString()).
                    replace(Constants.USERNAME, user.getUsername());
            if(param.getLockLife()!=null){
                content =content.replace(Constants.LOCKLIFE,param.getLockLife().toString());
            }
            if (param.getAmount()!=null){
                content =content.replace(Constants.MONEY, param.getAmount().toString());
            }*/
            Sms.send(user.getMobile(), rule.getNoticeContent());
            SysNotice notice = new SysNotice();
            notice.setTitle(title);
            notice.setUserId(param.getUserId());
            notice.setStatus(0);
            notice.setAddip(param.getAddIp());
            notice.setAddtime(now);
            notice.setTypee(1);
            notice.setReceiveId(user.getMobile());
            notice.setContents(rule.getNoticeContent());
            noticeMapper.insert(notice);
        }
        if (rule.getWhetherMail() == 1 && (appSettings == null || appSettings.getWhetherSiteMail() == 1)) {
            /*SysNoticeType sysNoticeType = noticeTypeMapper.getNoticeTypeByNid(param.getNid()+"_award_mail");
            if (sysNoticeType == null){
                return;
            }
            String content = sysNoticeType.getTypeContent().
                    replace(Constants.AWARDTYPE, type).
                    replace(Constants.AWARD,value.toString()).
                    replace(Constants.USERNAME, user.getUsername());
            if(param.getLockLife()!=null){
                content =content.replace(Constants.LOCKLIFE,param.getLockLife().toString());
            }
            if (param.getAmount()!=null){
                content =content.replace(Constants.MONEY, param.getAmount().toString());
            }*/
            SysSiteMail siteMail = new SysSiteMail();
            siteMail.setUserId(param.getUserId());
            siteMail.setContents(rule.getNoticeContent());
            siteMail.setStatus(0);
            siteMail.setTitle(title);
            siteMail.setAddtime(now);
            siteMail.setAddip(param.getAddIp());
            siteMail.setType(1);
            siteMail.setIsDelete(0);
            siteMailMapper.insert(siteMail);
        }
        if (rule.getWhetherAppPush() == 1 && (appSettings == null || appSettings.getWhetherAppPush() == 1)) {
            /*SysNoticeType sysNoticeType = noticeTypeMapper.getNoticeTypeByNid(param.getNid()+"_award_push");
            if (sysNoticeType == null){
                return;
            }*/
            SysAppClient appClient = appClientMapper.getAppClientByUserId(user.getId());
            if (appClient == null) {
                return;
            }
            /*String content = sysNoticeType.getTypeContent().
                    replace(Constants.AWARDTYPE, type).
                    replace(Constants.AWARD,value.toString()).
                    replace(Constants.USERNAME, user.getUsername());
            if(param.getLockLife()!=null){
                content =content.replace(Constants.LOCKLIFE,param.getLockLife().toString());
            }
            if (param.getAmount()!=null){
                content =content.replace(Constants.MONEY, param.getAmount().toString());
            }*/
            noticePush.getOnePush(appClient.getClientId(), title, rule.getNoticeContent());
            SysPushLog pushLog = new SysPushLog();
            pushLog.setTitle(title);
            pushLog.setUserId(param.getUserId());
            pushLog.setStatus(0);
            pushLog.setAddip(param.getAddIp());
            pushLog.setAddtime(now);
            pushLog.setType(1);
            pushLog.setClientId(appClient.getClientId());
            pushLog.setContents(rule.getNoticeContent());
            pushLogMapper.insert(pushLog);
        }
    }


    //根据锁定期限判断区间获取规则
    private SysConfigTicketRule getRuleWithLevel(Integer lockLife,
                                                 List<SysConfigTicketRule> ruleList) {
        sortByLockLife(ruleList);
        SysConfigTicketRule ret = new SysConfigTicketRule();
        for (int i = 0; i < ruleList.size(); i++) {
            if (lockLife < ruleList.get(i).getLockLife()) {
                return ret;
            } else {
                ret = ruleList.get(i);
            }
        }
        return ret;
    }

    //根据投资金额判断区间获取规则
    private SysConfigTicketRule getRuleWithLevel(BigDecimal amount,
                                                 List<SysConfigTicketRule> ruleList) {
        sortByAmount(ruleList);
        SysConfigTicketRule ret = new SysConfigTicketRule();
        for (int i = 0; i < ruleList.size(); i++) {
            if (amount.compareTo(ruleList.get(i).getMinimumAmount()) < 0) {
                return ret;
            } else {
                ret = ruleList.get(i);
            }
        }
        return ret;
    }

    //按最低投资金额从小到大排序规则
    private void sortByAmount(List<SysConfigTicketRule> ruleList) {
        for (int i = 0; i < ruleList.size() - 1; i++) {
            for (int j = i + 1; j < ruleList.size(); j++) {
                if (ruleList.get(i).getMinimumAmount().
                        compareTo(ruleList.get(j).getMinimumAmount()) > 0) {
                    SysConfigTicketRule temp = ruleList.get(i);
                    ruleList.set(i, ruleList.get(j));
                    ruleList.set(j, temp);
                }
            }
        }
    }

    //按锁定期限从小到大排序规则
    private void sortByLockLife(List<SysConfigTicketRule> ruleList) {
        for (int i = 0; i < ruleList.size() - 1; i++) {
            for (int j = i + 1; j < ruleList.size(); j++) {
                if (ruleList.get(i).getLockLife() > ruleList.get(i).getLockLife()) {
                    SysConfigTicketRule temp = ruleList.get(i);
                    ruleList.set(i, ruleList.get(j));
                    ruleList.set(j, temp);
                }
            }
        }
    }

    //判断是否是大于0的BigDecimal
    private boolean isPosDec(BigDecimal param) {
        if (param == null) {
            return false;
        }
        if (param.compareTo(new BigDecimal(0)) != 1) {
            return false;
        }
        return true;
    }

    //判断是否是大于0的Integer
    private boolean isPosInt(Integer param) {
        if (param == null) {
            return false;
        }
        if (param <= 0) {
            return false;
        }
        return true;
    }

    //增加天数
    private Date addDay(Date date, Integer days) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, days);
        return cd.getTime();
    }

    public Map setIntime(SysConfigTicketRule rule,List userList){
        //根据nid和投资类型获取可用的规则
        List<SysConfigTicketRule> ruleList = ticketRuleMapper.listUsableByNid(Constants.send_intime_nid);
        boolean doSend= false;
        for (SysConfigTicketRule sysRule : ruleList){
            System.out.println(sysRule.getId());
            System.out.println(rule.getId());
            if(sysRule.getId().intValue()== rule.getId().intValue()){
                doSend=true;
            }
        }
        if(doSend){
            for (Object obj:userList){
                TicketParamEntity param = new TicketParamEntity();
                if(obj instanceof UserVo){
                    param.setUserId(((UserVo) obj).getId());
                }
                if(obj instanceof SysConfigTicketUser){
                    param.setUserId(((SysConfigTicketUser) obj).getUserId());
                }
                dealInsertTicket(param, rule, 1);
            }
        }
        return Message.OK;
    }


}
